# 标量由只有一个元素的张量表示
import torch

x = torch.tensor([3.0])
y = torch.tensor([2.0])

print(x + y)
print(x * y)
print(x / y)
print(x ** y)

# 你可以将向量视为标量值组成的列表
x = torch.arange(4)
print(x)

# 通过张量的索引来访问任一元素
print(x[3])

# 访问张量的长度
print(len(x))

# 只有一个轴的张量，形状只有一个元素
print(x.shape)

# 通过指定两个分量m 和 n来创建一个形状为m×n的矩阵
A = torch.arange(20).reshape(5, 4)
print(A)

# 矩阵的转置
print(A.T)

# 对称矩阵（symmetric matrix）A 等于其转置：A=A⊤
B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
print(B)
print(B == B.T)

# 就像向量是标量的推广，矩阵是向量的推广一样，我们可以构建具有更多轴的数据结构
X = torch.arange(24).reshape(2, 3, 4)
print(X)

# 给定具有相同形状的任意两个张量，任何按元素二元运算的结果都将是相同形状的张量
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()
print(A)
print(A + B)

# 两个矩阵的按元素乘法称为哈达玛积（Hadamard product）（数学符号⊙）
print(A * B)
a = 2
X = torch.arange(24).reshape(2, 3, 4)
print(a + X)
print((a * X).shape)

# 计算其元素的和
x = torch.arange(4, dtype=torch.float32)
print(x)
print(x.sum())

# 表示任意形状张量的元素和
print(A.shape)
print(A.sum())

# 指定张量沿哪一个轴来通过求和降低维度
A_sum_axis0 = A.sum(axis=0)
print(A_sum_axis0)
print(A_sum_axis0.shape)
A_sum_axis1 = A.sum(axis=1)
print(A_sum_axis1)
print(A_sum_axis1.shape)
print(A.sum(axis=[0, 1]))

# 一个与求和相关的量是平均值（mean或average）
print(A.mean())
print(A.sum() / A.numel())
print(A.mean(axis=0))
print(A.sum(axis=0) / A.shape[0])

# 计算总和或均值时保持轴数不变
sum_A = A.sum(axis=1, keepdims=True)
print(sum_A)

# 通过广播将A除以sum_A
print(A / sum_A)

# 某个轴计算A元素的累积总和
A.cumsum(axis=0)

# 点积是相同位置的按元素乘积的和
y = torch.ones(4, dtype=torch.float32)
print(x)
print(y)
print(torch.dot(x, y))

# 我们可以通过执行按元素乘法，然后进行求和来表示两个向量的点积
print(torch.sum(x * y))

# 矩阵向量积Ax 是一个长度为m 的列向量，其第i个元素是点积a⊤ix
print(A.shape)
print(x.shape)
print(torch.mv(A,x))

# 我们可以将矩阵-矩阵乘法AB看作是简单地执行m次矩阵-向量积，并将结果拼接在一起，形成一个n×m矩阵
B = torch.ones(4, 3)
print(torch.mm(A, B))

# L2范数是向量元素平方和的平方根：
u = torch.tensor([3.0, -4.0])
print(torch.norm(u))

# L1范数，它表示为向量元素的绝对值之和
print(torch.abs(u).sum())

# 矩阵 的弗罗贝尼乌斯范数（Frobenius norm）是矩阵元素平方和的平方根：
print(torch.norm(torch.ones((4, 9))))